﻿using FlyRemote.Remote;
using System;

namespace FlyRemote.Base
{
    /// <summary>
    /// 定义了一个进程的连续内存段，多个快照间可以共享一个 ReadGroup 
    /// ftp://note 这里是纯输入端, 不保存结果 , 也不需要知道结果类型的存在 
    /// </summary>
    public class ReadGroup : NormalizedRegion, IDisposable
    {
        public ReadGroup(DataType type, UInt64 baseAddress, int regionSize, int alignment, bool isModule = false) : base(baseAddress, regionSize)
        {
            this.ElementDataType = type;
            this.Alignment = alignment;

            // !!! 此处代码遗漏 ， 造成无法基址定位
            this.IsModuleRegion = isModule;
        }



        public override string ToString()
        {
            return $"{BaseAddress:X} -- {EndAddress:X}";
        }


        public DataType ElementDataType { get; set; }




        #region 数据 
        /// <summary>
        /// 是否模块空间 ，用来查找基址 
        /// </summary>
        public bool IsModuleRegion { get; set; } = false;


        public Byte[] CurrentValues { get; set; }

        /// <summary>
        /// 获取以前读取的值。
        /// </summary>
        public Byte[] PreviousValues { get; private set; }



        /// <summary>
        /// 元素标签
        /// </summary>
        public Object[] ElementLabels { get; private set; }

        /// <summary>
        /// 发现 标志
        /// </summary>
        public bool FoundFlag { get; set; }


        #endregion

        /// <summary>
        /// 读取该内存区域的所有内存。
        /// </summary>
        //public Boolean ReadAllValues()
        //{
        //    Boolean readSuccess;


        //    if (CurrentValues == null)
        //    {
        //        CurrentValues = RMFactory.Default.ReadBytes(this.BaseAddress, this.RegionSize, out readSuccess);
        //    }
        //    else if (PreviousValues == null)
        //    {
        //        var tmp = CurrentValues;
        //        CurrentValues = RMFactory.Default.ReadBytes(this.BaseAddress, this.RegionSize, out readSuccess);
        //        PreviousValues = tmp;
        //    }
        //    else
        //    {
        //        /// ftp://note 此处并不会再分配内存, 防止给gc 产生压力 

        //        var tmp = PreviousValues;
        //        PreviousValues = CurrentValues;  // 旧数据指向当前 
        //        CurrentValues = tmp;    // 当前数据 指向旧数据 ,用以 更新  

        //        readSuccess = RMFactory.Default.ReadBytes(this.BaseAddress, CurrentValues, this.RegionSize);
        //    }


        //    return readSuccess;
        //}


        /// <summary>
        /// 只更新 当前值, 而不处理历史值 
        /// </summary>
        public bool ReadCurrentValues()
        {
            Boolean readSuccess;

            if (CurrentValues == null)
            {
                CurrentValues = RMFactory.Default.ReadBytes(this.BaseAddress, this.RegionSize, out readSuccess);
            }
            else
            {
                readSuccess = RMFactory.Default.ReadBytes(this.BaseAddress, CurrentValues, this.RegionSize);
            }

            return readSuccess;
        }


        /// <summary>
        /// 是否可以对该区域进行相对比较
        /// 当前数值为空的情况  或   历史值为空,却需要进行 前后比较的 
        /// </summary>
        public Boolean CanCompare(Boolean hasRelativeConstraint)
        {
            if (this.CurrentValues == null || (hasRelativeConstraint && this.PreviousValues == null))
            {
                return false;
            }

            return true;
        }

        public void Dispose()
        {
            throw new NotImplementedException();
        }


        // 添加 group 的读取方法 
        //public object Read(DataType dataType, ulong address, out bool success)
        //{
        //    success = false;

        //    if (this.BaseAddress <= address && address < this.EndAddress)
        //    {
        //        if (this.CurrentValues != null)
        //        {
        //            success = true;
        //            return dataType.FromBytes(this.CurrentValues, (int)(address - this.BaseAddress));
        //        }

        //        return null;
        //    }

        //    return null;
        //}


    }
}
